package com.bianqian.demo.controller;

import com.bianqian.demo.dto.*;
import com.bianqian.demo.entity.Category;
import com.bianqian.demo.service.CategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 分类控制器
 */
@RestController
@RequestMapping("/api/category")
@RequiredArgsConstructor
@Slf4j
@Validated
public class CategoryController {
    
    private final CategoryService categoryService;
    
    /**
     * 获取分类列表
     * @param request HTTP请求
     * @return 分类列表
     */
    @GetMapping("/list")
    public ApiResponse<List<CategoryDto>> getCategoryList(HttpServletRequest request) {
        try {
            Long userId = (Long) request.getAttribute("userId");
            log.info("获取分类列表请求，用户ID：{}", userId);
            
            List<Category> categories = categoryService.getCategoriesByUserId(userId);
            List<CategoryDto> categoryDtos = categories.stream()
                    .map(category -> new CategoryDto(
                            category.getId(),
                            category.getName(),
                            category.getCount(),
                            category.getCreatedAt(),
                            category.getUpdatedAt()
                    ))
                    .collect(Collectors.toList());
            
            log.info("分类列表获取成功，用户ID：{}，分类数量：{}", userId, categoryDtos.size());
            return ApiResponse.success("获取成功", categoryDtos);
            
        } catch (Exception e) {
            log.error("获取分类列表异常：", e);
            return ApiResponse.error("获取分类列表失败，请重试");
        }
    }
    
    /**
     * 创建分类
     * @param request HTTP请求
     * @param createRequest 创建请求
     * @return 创建的分类
     */
    @PostMapping("/create")
    public ApiResponse<CategoryDto> createCategory(HttpServletRequest request, 
                                                  @Valid @RequestBody CreateCategoryRequest createRequest) {
        try {
            Long userId = (Long) request.getAttribute("userId");
            log.info("创建分类请求，用户ID：{}，分类名称：{}", userId, createRequest.getName());
            
            Category category = categoryService.createCategory(userId, createRequest.getName());
            CategoryDto categoryDto = new CategoryDto(
                    category.getId(),
                    category.getName(),
                    category.getCount(),
                    category.getCreatedAt(),
                    category.getUpdatedAt()
            );
            
            log.info("分类创建成功，用户ID：{}，分类ID：{}", userId, category.getId());
            return ApiResponse.success("创建成功", categoryDto);
            
        } catch (RuntimeException e) {
            log.error("创建分类失败：{}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("创建分类异常：", e);
            return ApiResponse.error("创建分类失败，请重试");
        }
    }
    
    /**
     * 更新分类
     * @param request HTTP请求
     * @param updateRequest 更新请求
     * @return 更新后的分类
     */
    @PutMapping("/update")
    public ApiResponse<CategoryDto> updateCategory(HttpServletRequest request, 
                                                  @Valid @RequestBody UpdateCategoryRequest updateRequest) {
        try {
            Long userId = (Long) request.getAttribute("userId");
            log.info("更新分类请求，用户ID：{}，分类ID：{}，新名称：{}", 
                    userId, updateRequest.getId(), updateRequest.getName());
            
            Category category = categoryService.updateCategory(userId, updateRequest.getId(), updateRequest.getName());
            CategoryDto categoryDto = new CategoryDto(
                    category.getId(),
                    category.getName(),
                    category.getCount(),
                    category.getCreatedAt(),
                    category.getUpdatedAt()
            );
            
            log.info("分类更新成功，用户ID：{}，分类ID：{}", userId, category.getId());
            return ApiResponse.success("更新成功", categoryDto);
            
        } catch (RuntimeException e) {
            log.error("更新分类失败：{}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("更新分类异常：", e);
            return ApiResponse.error("更新分类失败，请重试");
        }
    }
    
    /**
     * 删除分类
     * @param request HTTP请求
     * @param deleteRequest 删除请求
     * @return 删除结果
     */
    @DeleteMapping("/delete")
    public ApiResponse<Object> deleteCategory(HttpServletRequest request, 
                                            @Valid @RequestBody DeleteCategoryRequest deleteRequest) {
        try {
            Long userId = (Long) request.getAttribute("userId");
            log.info("删除分类请求，用户ID：{}，分类ID：{}", userId, deleteRequest.getId());
            
            categoryService.deleteCategory(userId, deleteRequest.getId());
            
            log.info("分类删除成功，用户ID：{}，分类ID：{}", userId, deleteRequest.getId());
            return ApiResponse.success("删除成功", null);
            
        } catch (RuntimeException e) {
            log.error("删除分类失败：{}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("删除分类异常：", e);
            return ApiResponse.error("删除分类失败，请重试");
        }
    }
    
    /**
     * 获取分类详情
     * @param request HTTP请求
     * @param id 分类ID
     * @return 分类详情
     */
    @GetMapping("/detail")
    public ApiResponse<CategoryDto> getCategoryDetail(HttpServletRequest request, 
                                                    @RequestParam Long id) {
        try {
            Long userId = (Long) request.getAttribute("userId");
            log.info("获取分类详情请求，用户ID：{}，分类ID：{}", userId, id);
            
            Category category = categoryService.getCategoryDetail(userId, id);
            CategoryDto categoryDto = new CategoryDto(
                    category.getId(),
                    category.getName(),
                    category.getCount(),
                    category.getCreatedAt(),
                    category.getUpdatedAt()
            );
            
            log.info("分类详情获取成功，用户ID：{}，分类ID：{}", userId, id);
            return ApiResponse.success("获取成功", categoryDto);
            
        } catch (RuntimeException e) {
            log.error("获取分类详情失败：{}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("获取分类详情异常：", e);
            return ApiResponse.error("获取分类详情失败，请重试");
        }
    }
    
    /**
     * 更新分类统计
     * @param request HTTP请求
     * @param updateCountRequest 更新统计请求
     * @return 更新后的分类
     */
    @PostMapping("/updateCount")
    public ApiResponse<CategoryDto> updateCategoryCount(HttpServletRequest request, 
                                                       @Valid @RequestBody UpdateCategoryCountRequest updateCountRequest) {
        try {
            Long userId = (Long) request.getAttribute("userId");
            log.info("更新分类统计请求，用户ID：{}，分类ID：{}，操作：{}", 
                    userId, updateCountRequest.getCategoryId(), updateCountRequest.getOperation());
            
            Category category = categoryService.updateCategoryCount(
                    userId, 
                    updateCountRequest.getCategoryId(), 
                    updateCountRequest.getOperation()
            );
            
            CategoryDto categoryDto = new CategoryDto(
                    category.getId(),
                    category.getName(),
                    category.getCount(),
                    category.getCreatedAt(),
                    category.getUpdatedAt()
            );
            
            log.info("分类统计更新成功，用户ID：{}，分类ID：{}，新数量：{}", 
                    userId, category.getId(), category.getCount());
            return ApiResponse.success("统计更新成功", categoryDto);
            
        } catch (RuntimeException e) {
            log.error("更新分类统计失败：{}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("更新分类统计异常：", e);
            return ApiResponse.error("更新分类统计失败，请重试");
        }
    }
    
    /**
     * 获取分类下的笔记列表
     * @param request HTTP请求
     * @param categoryId 分类ID
     * @return 笔记列表
     */
    @GetMapping("/{categoryId}/notes")
    public ApiResponse<List<NoteDto>> getNotesByCategory(HttpServletRequest request, 
                                                        @PathVariable Long categoryId) {
        try {
            Long userId = (Long) request.getAttribute("userId");
            log.info("获取分类笔记列表请求，用户ID：{}，分类ID：{}", userId, categoryId);
            
            List<NoteDto> notes = categoryService.getNotesByCategory(userId, categoryId);
            
            log.info("分类笔记列表获取成功，用户ID：{}，分类ID：{}，笔记数量：{}", 
                    userId, categoryId, notes.size());
            return ApiResponse.success("获取成功", notes);
            
        } catch (RuntimeException e) {
            log.error("获取分类笔记列表失败：{}", e.getMessage());
            return ApiResponse.error(400, e.getMessage() != null ? e.getMessage() : "获取分类笔记列表失败");
        } catch (Exception e) {
            log.error("获取分类笔记列表异常：", e);
            return ApiResponse.error(500, "获取分类笔记列表失败，请重试");
        }
    }
}




